//
// Created by xunx on 2018/12/6.
//

#include "Window.h"
#include "Display.h"

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);

void mouse_button_callback(GLFWwindow* window, int button, int action, int mods);

void mouse_Pos_callback(GLFWwindow* window, double xpos, double ypos);


void Window::InitGLFW() {
    assert(glfwInit());
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_RESIZABLE, false);
}

void Window::InitGLAD() {
    assert(gladLoadGLLoader((GLADloadproc) glfwGetProcAddress));
}

void Window::InitGLFWWindow(int width, int height, const char* title) {
    window = glfwCreateWindow(width, height, title, nullptr, nullptr);
    if (window == nullptr) {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return;
    }
    glfwMakeContextCurrent(window);
    glfwSetKeyCallback(window, key_callback);
    glfwSetMouseButtonCallback(window, mouse_button_callback);
    glfwSetCursorPosCallback(window, mouse_Pos_callback);
}

Window::Window(int width, int height, const char* title) {
    InitGLFW();
    InitGLFWWindow(width, height, title);
    InitGLAD();
    display = new Display();

}

Window::~Window() {
    delete display;
    glfwTerminate();
}

bool Window::WindowShouldClose() {
    return !glfwWindowShouldClose(window);
}

void Window::WindowsClear() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

void Window::Update() {
    WindowsClear();
    display->Show();
    glfwSwapBuffers(window);
}

void Window::GameTick(float deltaTime) {
    glfwPollEvents();
}


int Window::GetMousebuttonIsPress(int key) {
    return MOUSEBUTTON[key];
}

glm::vec2 Window::GetMousePosition() {
    return MousePosition;
}

int Window::GetKeysIsPress(int key) {
    return Keys[key];
}


void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
    Keys[key] = action;

}

void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) {
    MOUSEBUTTON[button] = action;

}

void mouse_Pos_callback(GLFWwindow* window, double xpos, double ypos) {
    MousePosition.x = xpos;
    MousePosition.y = ypos;
}